﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SharpPcap.WinPcap;
using SharpPcap;
using System.Collections;
using PacketDotNet;
using System.Threading;
using BasePlatformCommon.devChain;

namespace BasePlatformNet
{
	public class PacketReceiver
	{
		private bool useUDP = true;			// 是否使用 UDP 协议

		public NetDevice reveiveDevice;		// 接收设备

		private string depthPosition = DepthReadPos.Pos_59_61;	// 分控/附属设备级联深度读取位置, 默认59、61字节

		private Hashtable cmdReplyInfoTable = null;	// 暂未用

		private bool fillFlashDataFlag = false;		// 数据填充标记 - 用于批量读取Flash（目前为固件区）

        public byte[] readDataBuffer = null;		// 接收数据缓存 - 用于批量读取Flash（目前为固件区）

        public event Action<ArtPacket, string, string> ArtMessageReceiveHandle;
        public event Action<string> ARPMessageReceiveHandle;

        public int cnt = 0;

		// 构造函数
		public PacketReceiver()
		{
			cmdReplyInfoTable = new Hashtable();
		}

		// 设置接收设备
		public void setDevice(NetDevice device)
		{
			reveiveDevice = device;

			reveiveDevice.pcapDevice.OnPacketArrival += new PacketArrivalEventHandler(device_OnPacketArrival);

			device.packetReceiver = this;
		}

		// 设置分控/附属设备级联深度读取位置
		public void setDepthReadPosition(string readPos)
		{
			depthPosition = readPos;
		}

		// 返回设备打开状态
		public bool isOpened()
		{
			return reveiveDevice.pcapDevice.Opened;
		}

		// 接收器设置为读取 Flash 状态 - 接收通信反馈包并填充数据
		public string startReadFlash(int dataLength)
		{
			if (fillFlashDataFlag == true)
			{
				return "Error: another read operation is processing.";
			}
			else
			{
				fillFlashDataFlag = true;
				readDataBuffer = new byte[dataLength];
				return "success";
			}
		}

		// 接收器重置读取 Flash 状态 - 不填充数据
		public void stopReadFlash()
		{
			fillFlashDataFlag = false;
		}

		// SharpPcap 抓包回调函数
		private void device_OnPacketArrival(object sender, CaptureEventArgs e)
		{
			PcapPorcessContext_Quick(e);
		}
        int n = 0;
		// SharpPcap 抓包处理 - 快速
		private void PcapPorcessContext_Quick(CaptureEventArgs e)
		{
			try
			{
				var layer = e.Packet.LinkLayerType;

				var packet = PacketDotNet.Packet.ParsePacket(e.Packet.LinkLayerType, e.Packet.Data);	// Raw 基础包对象

				if (layer != PacketDotNet.LinkLayers.Ethernet)	// 以太网包
				{
					return;
				}

				// UDP协议
				if (useUDP)
				{
					IpPacket ipPacket = (IpPacket)packet.Extract(typeof(IpPacket));  // IP包
                    byte[] sourceMac = new byte[6];
                    Tools.CopyByte(ref sourceMac, packet.Bytes, 6, 0, 6);
					if (ipPacket != null)
					{
						UdpPacket udpPacket = (UdpPacket)ipPacket.Extract(typeof(UdpPacket)); // UDP包
						if (udpPacket != null)
						{
							// 目的端口
							int destPort = udpPacket.DestinationPort;

							//if (destPort == 21930)
							//{
							//	Log.NormalLogger.Warn("Receive Local Packet");
							//	packetAnalyze(ipPacket.Bytes);
							//}
                            if (destPort == 23205) {
                                packetAnalyze(ipPacket.Bytes);
                            }
                            else if (destPort == BaseCoreNet.ArtNetPort) {
                                ArtNetpacketAnalyze(ipPacket.Bytes, Tools.Byte2HexString(sourceMac).Replace("\n",""));
                            }
                            //else if ((packet.Bytes[12] == 0x08) && (packet.Bytes[13] == 0x06))
                            //{
                            //    ARPPacket arpPacket = (ARPPacket)packet.Extract(typeof(ARPPacket));
                            //    ARPMessageAnalyze(arpPacket);
                            //}
						}
					}
				}
				// 自定协议
                else if (packet.Bytes.Length > 14)
                {

                    byte[] destMAC = new byte[6];
                    byte[] srcMAC = new byte[6];
                    byte[] type = new byte[2];
                    byte[] data = new byte[28 + packet.Bytes.Length - 14];

                    Array.Copy(packet.Bytes, 0, destMAC, 0, 6);
                    Array.Copy(packet.Bytes, 6, srcMAC, 0, 6);
                    Array.Copy(packet.Bytes, 12, type, 0, 2);
                    Array.Copy(packet.Bytes, 14, data, 28, data.Length - 28);

                    if (Tools.Byte2HexString(destMAC).Equals("FFFFFFFFFFFF\n") && Tools.Byte2HexString(srcMAC).Equals("000000000000\n"))
                    {
                        packetAnalyze(data);
                    }
                }
			}
			catch(Exception ex)
			{
                Console.WriteLine(ex.ToString());
				return;
			}
		}

		// 业务逻辑抓包处理
		private void packetAnalyze(byte[] packetData)
		{
			LEDPacket myPacket = new LEDPacket(packetData);

			// 收到通信应答包
			if (myPacket.packetType == LEDPacket.TYPE_CONM_REPLY)
			{
				// 通信应答包 - 用于在线检测 - 分控, 编号范围 100~399, 实际为 100 + targetDepth
				if (myPacket.cmdPacketID >= 100 && myPacket.cmdPacketID <= 399)
				{
					ControlNode subNode = new ControlNode(1);
					
					// 在 54_56 字节或者 59_61 字节读取级联深度, 默认 59_61 字节
					if (depthPosition.Equals("54_56"))
					{
						subNode.mySubCtrlDepth = myPacket.subCtrlDepth;
						subNode.myEquipmentDepth = myPacket.equipmentDepth;
					}
					else if (depthPosition.Equals("59_61"))
					{
						subNode.mySubCtrlDepth = myPacket.subCtrlDepth2 - 1;
						if (subNode.mySubCtrlDepth < 0)
						{
							subNode.mySubCtrlDepth = 0;
						}

						subNode.myEquipmentDepth = myPacket.equipmentDepth2 - 1;
						if (subNode.myEquipmentDepth < 0)
						{
							subNode.myEquipmentDepth = 0;
						}
					}

					// 采用 cmdPacketID - 100 - 1 的方式计算分控级联深度, 用于支持交换机
					subNode.mySubCtrlDepth = myPacket.cmdPacketID - 100 - 1;
					subNode.version = myPacket.firmwareVersion;
                    subNode.subType = myPacket.subType;
					
					// 反馈的全部数据 - 256字节
					Array.Copy(myPacket.replyData, 0, subNode.replyData, 0, subNode.replyData.Length);

					// for debug
					//for (int i = 0; i < 256; i++)
					//{
					//	subNode.replyData[i] = 0x01;
					//}

					if (reveiveDevice.currentOperFlag == 0)
					{
						reveiveDevice.subCtrlList_0.Add(subNode);
					}
					else
					{
						reveiveDevice.subCtrlList_1.Add(subNode);
					}

                    cnt++;
                    if (cnt > 1000000) {
                        cnt = 0;
                    }
                    if (cnt % 100 == 0) {
                        //BasePlatformCommon.Log.DebugLogger.Info("detectReceived");
                    }
				}
				// 通信应答包 - 用于在线检测 - 附属设备, 编号范围 400~499, 实际为 400 + targetDepth
				else if (myPacket.cmdPacketID >= 400 && myPacket.cmdPacketID <= 499)
				{
					ControlNode equNode = new ControlNode(0);

					// 在 54_56 字节或者 59_61 字节读取级联深度
					if (depthPosition.Equals("54_56"))
					{
						equNode.mySubCtrlDepth = myPacket.subCtrlDepth;
						equNode.myEquipmentDepth = myPacket.equipmentDepth;
					}
					else if (depthPosition.Equals("59_61"))
					{
						equNode.mySubCtrlDepth = myPacket.subCtrlDepth2 - 1;
						if (equNode.mySubCtrlDepth < 0)
						{
							equNode.mySubCtrlDepth = 0;
						}
						equNode.myEquipmentDepth = myPacket.equipmentDepth2 - 1;
						if (equNode.myEquipmentDepth < 0)
						{
							equNode.myEquipmentDepth = 0;
						}
					}

					// 采用 cmdPacketID - 400 - 1 的方式计算附属设备级联深度, 用于支持交换机
					equNode.myEquipmentDepth = myPacket.cmdPacketID - 400 - 1;
					equNode.version = myPacket.firmwareVersion;
					
					// 反馈的全部数据 - 256字节
					Array.Copy(myPacket.replyData, 0, equNode.replyData, 0, equNode.replyData.Length);

					if (reveiveDevice.currentOperFlag == 0)
					{
						reveiveDevice.equipmentList_0.Add(equNode);
					}
					else
					{
						reveiveDevice.equipmentList_1.Add(equNode);
					}
				}
				// 通信应答包 - 用于上层应用 读分控，编号范围 1000~2999
				else if (myPacket.cmdPacketID >= 1000 && myPacket.cmdPacketID <= 2999)
				{
					Array.Copy(myPacket.replyData, reveiveDevice.readSubReplyList[myPacket.cmdPacketID].replyData, 256);
					reveiveDevice.readSubReplyList[myPacket.cmdPacketID].doneEvent.Set();
				}
				// 通信应答包 - 用于上层应用 读附属设备，编号范围 5000~6999
				else if (myPacket.cmdPacketID >= 5000 && myPacket.cmdPacketID <= 6999)
				{
					Array.Copy(myPacket.replyData, reveiveDevice.readEquReplyList[myPacket.cmdPacketID].replyData, 256);
					reveiveDevice.readEquReplyList[myPacket.cmdPacketID].doneEvent.Set();
				}
				// 读取 Flash 固件区，编号范围 20000~201024
				else if (myPacket.cmdPacketID >= 20000 && myPacket.cmdPacketID < 201024)
				{
					// 当前为读取 Flash 模式
					if (fillFlashDataFlag == true)
					{
						Array.Copy(myPacket.replyData, 0, readDataBuffer, (myPacket.cmdPacketID - 20000) * 256, 256);
					}
				}
			}
		}

        private void ArtNetpacketAnalyze(byte[] packet, string sourceMac) {
            if (packet.Length <= 28) {
                return;
            } else {
                int len = packet.Length - 28;
                byte[] artpacket = new byte[len];
                Tools.CopyByte(ref artpacket, packet, len, 0, 28);
                ArtPacket artnetPac = ArtPacket.decodePacket(artpacket);
                string sourceIP = String.Format("{0}.{1}.{2}.{3}", packet[12], packet[13], packet[14], packet[15]);
                string targetIP = String.Format("{0}.{1}.{2}.{3}", packet[16], packet[17], packet[18], packet[19]);
                if (ArtMessageReceiveHandle != null) {
                    ArtMessageReceiveHandle(artnetPac, sourceIP, sourceMac);
                    //Console.WriteLine("receive - {0} code:{1}", n++, (ArtPacketType)artnetPac.OpCode);
                }

            }
        }

        private void ARPMessageAnalyze(ARPPacket packet) {
            string mac = packet.TargetHardwareAddress.ToString();
            if (mac.Equals(reveiveDevice.mac)) {
                if (ARPMessageReceiveHandle != null) {
                    ARPMessageReceiveHandle(packet.SenderProtocolAddress.ToString());
                }
            }
        }
	}
}
